﻿using System;
using System.Runtime.InteropServices;
namespace Commands
{
    public static class NativeClipboard
    {
        [DllImport("user32.dll")]
        private static extern bool OpenClipboard(IntPtr hWndNewOwner);

        [DllImport("user32.dll")]
        private static extern bool EmptyClipboard();

        [DllImport("user32.dll")]
        private static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);

        [DllImport("user32.dll")]
        private static extern bool CloseClipboard();

        [DllImport("kernel32.dll")]
        private static extern IntPtr GlobalLock(IntPtr hMem);

        [DllImport("kernel32.dll")]
        private static extern bool GlobalUnlock(IntPtr hMem);

        [DllImport("kernel32.dll")]
        private static extern IntPtr GlobalAlloc(uint uFlags, UIntPtr dwBytes);

        public static void SetText(string text)
        {
            const uint CF_UNICODETEXT = 13;

            if (!OpenClipboard(IntPtr.Zero))
                throw new Exception("无法打开剪贴板");

            try
            {
                EmptyClipboard();

                // 分配全局内存
                IntPtr hGlobal = GlobalAlloc(0x42, (UIntPtr)((text.Length + 1) * 2));
                IntPtr source = Marshal.StringToHGlobalUni(text);

                // 复制数据
                IntPtr target = GlobalLock(hGlobal);
                CopyMemory(target, source, (uint)(text.Length * 2));
                GlobalUnlock(hGlobal);
                Marshal.FreeHGlobal(source);

                // 设置剪贴板数据
                SetClipboardData(CF_UNICODETEXT, hGlobal);
            }
            finally
            {
                CloseClipboard();
            }
        }

        [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
        private static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
    }
}